package 线程2;
//此处不太懂
//     * 2.还可以使用,标准库里面内置的标记.
//             * 获取线程内置的标记位:线程的isinterrupted()判断当前线程是不是应该要结束循环 Thread.currentThread().isInterrupted();
//             * 修改线程内置的标记位:Thread.interrupt()来修改这个标记位
public class TestDemo3 {
//    比光使用标记位要好一些,如果用第一种也遇到了睡眠这种情况,就没法处理
    public static void main(String[] args) {
            Thread t = new Thread(){
                @Override
                public void run() {
                    //默认情况下,isInterrupted值为false
                    while(!Thread.currentThread().isInterrupted()){
                        System.out.println("线程运行中...");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            //在这加个break,就可以保证循环能够结束了
//                            break;
                            //触发异常之后,如果我们不做任何处理,循环还是会继续执行.为了让循环结束,加个break就行
                        }
                    }
                }
            };
        t.start();
        //在主线程中,通过t.interrupt()方法来设置这个标记位
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //这个操作就是把Thread.currentThread().isInterrupted()设置成true
        t.interrupt();
        /**
         * 当3s过后,interrupt()貌似并没有修改这个标记位,循环看起来还是在继续执行,同时这里有个异常
         */
        //这里的interrupt方法可能有两种行为:
//        1.如果当前线程正在运行中,此时就会修改Thread.currentThread().isInterrupted()标记为true;
//        2.如果当前线程正在sleep/wait/等待锁,,,此时就会触发InterruptedException

//        如果正在睡眠中,把标记位改了,也没用,线程还是会继续等待.所以有两手准备,
//        如果没在等待就置这个标记位true,如果已经正在休眠,那么通过异常的手段,把他唤醒
        /**
         * isInterrupted()是Thread的实例方法
         * 和这个方法还有一个类似的:
         * interrupted()这个是Thread的类方法(sttic)
         *
         * 这两者区别:
         * 使用这个静态的方法,会自动清楚标记位.
         * 例如,调用interrupt()方法,把标记位设为true.就应该结束循环.
         * 当调用静态的interrupted()来判定标记位的时候,就会返回true,同时还会把标记位再改回false
         * 下次再调用interrupted()就返回false;
         * (开关按下去,会自动弹起来)
         * 如果是调用非静态的isInterrupted()来判定标记位,也会返回true.
         * 同时不会对标记位进行修改.后边再调用isInterrupted()的时候,就仍然返回true
         * (开关按下去,不会自动弹起来)
         */
    }
}
